package com.test.exoplayertest.player.manager;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.test.exoplayertest.R;
import com.test.exoplayertest.player.gesture.GestureCallback;
import com.test.exoplayertest.player.interfaces.PlayerEventInterface;
import com.test.exoplayertest.player.utils.PlayerUtil;
import com.test.exoplayertest.player.view.PlayerFloatView;

import java.lang.ref.WeakReference;

/**
 * @author wuxiaotao on 2017/6/15.
 */

public class PlayerManager implements PlayerEventInterface<ViewGroup> {

    private PlayerControl mPlayerControl;
    private ViewControl mViewControl;
    private OrientationManager mOrientationManager;
    private ComponentListener mComponentListener;
    private WeakReference<Context> mContextWeakReference;
    private boolean isVideoFirstFrame = false; //视频加载到textureView上
    public static final String TAG = "PlayerManager";

    public PlayerManager(Activity context) {
        init(context);
    }

    public void init(Activity context) {
        mContextWeakReference = new WeakReference<Context>(context);
        mViewControl = new ViewControl(context);
        mPlayerControl = new PlayerControl(context);
        mComponentListener = new ComponentListener();
        mViewControl.setGestureListenner(new SimpleGestureCallBack());
        mViewControl.setChildClickListenner(mComponentListener);
        mOrientationManager = new OrientationManager(context);
    }

    @Override
    public void attach(ViewGroup viewGroup) {
        if (null == mPlayerControl || null == mViewControl) {
            throw new NullPointerException("view controll or player controll is null");
        }
        mViewControl.attach(viewGroup);
        mPlayerControl.attach(mViewControl.getTextureView());
        bind();
    }

    @Override
    public void detach() {
        mViewControl.detach();
        mPlayerControl.detach();
    }

    @Override
    public void startPlay(String url, String type) {
        mViewControl.startPlay(url, type);
        mPlayerControl.startPlay(url, type);
    }

    @Override
    public void release() {
        mViewControl.release();
        mPlayerControl.release();
    }

    @Override
    public void resume() {
        mPlayerControl.attach(mViewControl.getTextureView());
        mPlayerControl.resume();
        mViewControl.resume();
        bind();
    }

    private void bind() {
        SimpleExoPlayer exoPlayer = mPlayerControl.getExoPlayer();
        exoPlayer.removeListener(mComponentListener);
        exoPlayer.addListener(mComponentListener);
        exoPlayer.clearVideoListener(mComponentListener);
        exoPlayer.setVideoListener(mComponentListener);
        mViewControl.setExoPlayer(exoPlayer);
    }

    public void setSensorEnable(boolean enable) {
        if (null != mOrientationManager) {
            mOrientationManager.setSensorEnable(enable);
        }
    }

    private final class ComponentListener implements ExoPlayer.EventListener, SimpleExoPlayer.VideoListener, View.OnClickListener {

        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest) {
            Log.e(TAG, "====onTimelineChanged=====");
        }

        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
            Log.e(TAG, "====onTracksChanged=====");
        }

        @Override
        public void onLoadingChanged(boolean isLoading) {
            Log.e(TAG, "====onLoadingChanged isLoading=====" + isLoading);
        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            mPlayerControl.setKeepScreenOn(playWhenReady);
            switch (playbackState) {
                case ExoPlayer.STATE_READY:
                    Log.e(TAG, "====正在播放=====");
                    break;
                case ExoPlayer.STATE_BUFFERING:
                    Log.e(TAG, "====正在缓存=====" + playbackState);
                    break;
                case ExoPlayer.STATE_IDLE:
                    Log.e(TAG, "====播放暂停=====");
                    break;
                case ExoPlayer.STATE_ENDED:
                    Log.e(TAG, "====播放结束=====");
                    break;
            }
        }

        @Override
        public void onPlayerError(ExoPlaybackException error) {
            Log.e(TAG, "====播放错误=====" + error.type);
            String msg = PlayerFloatView.SOURCE_ERROR_MSG;
            boolean isConnect = PlayerUtil.isNetWorkAvaliable(mContextWeakReference.get());
            if (!isConnect) {
                msg = PlayerFloatView.NO_NET_ERROR_MSG;
            }
            mViewControl.showErrorView(msg, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mPlayerControl.resume();
                    mViewControl.resume();
                }
            });
        }

        @Override
        public void onPositionDiscontinuity() {
            //进度seekTo触发
            ExoPlayer exoPlayer = mPlayerControl.getExoPlayer();
            if (exoPlayer.getCurrentPosition() != exoPlayer.getDuration()) {
                isVideoFirstFrame = false;
                mViewControl.showLoadingView();
            }
            Log.e(TAG, "====onPositionDiscontinuity=====");
        }

        @Override
        public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
            Log.e(TAG, "====onPlaybackParametersChanged=====" + playbackParameters.speed);
        }

        @Override
        public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
            Log.e(TAG, "====onVideoSizeChanged=====" + unappliedRotationDegrees);
        }

        @Override
        public void onRenderedFirstFrame() {
            isVideoFirstFrame = true;
            //获取到第一帧图片触发  初次播放和快进时
            mViewControl.hideShutterView();
            mViewControl.hideFloatView();
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.orientation_btn: //横竖屏点击
                    mOrientationManager.setOrientationBtnClick();
                    break;
            }

        }
    }

    public void onConfigurationChanged(Configuration newConfig) {
        boolean isLand = mOrientationManager.isPlayerIsLand();
        mViewControl.onConfigurationChanged(isLand);
    }

    private final class SimpleGestureCallBack extends GestureCallback {

        private final long MAX_PROGRESS_TIME = 3 * 60 * 1000;
        private long downProgress, duration;


        @Override
        public void onDown() {
            mPlayerControl.updateDownVolume();
            mPlayerControl.updateDownBrightness();
            ExoPlayer exoPlayer = mPlayerControl.getExoPlayer();
            duration = exoPlayer.getDuration();
            downProgress = exoPlayer.getCurrentPosition();
            super.onDown();
        }

        @Override
        public void onSingleTapUp() {
            if (null != mViewControl) {
                mViewControl.onPanelViewClick();
            }
        }

        @Override
        public void onDoubleTap() {
            Log.e("WXT", "========onDoubleTap===========");
        }

        @Override
        public void onRightScroll(float incremental) {
            int volumeValue = mPlayerControl.setVolume(incremental);
            mViewControl.onVolumeChanged(volumeValue, mPlayerControl.getMaxVolume());
        }

        @Override
        public void onLeftScroll(float incremental) {
            int brightness = mPlayerControl.setBrightness(incremental);
            mViewControl.onBrightnessChanged(brightness, PlayerControl.MAX_BRIGHTNESS_VALUE);
        }

        @Override
        public void onLandscapeScroll(float incremental) {
            mViewControl.showPanelView();
            long progress = (long) (incremental * MAX_PROGRESS_TIME);
            mViewControl.onSeekProgressChanged(downProgress + progress, duration);

        }

        @Override
        public void onLandscapeScrollFinish(float incremental) {
            long progress = (long) (incremental * MAX_PROGRESS_TIME);
            ExoPlayer exoPlayer = mPlayerControl.getExoPlayer();
            long newProgress = downProgress + progress;
            if (newProgress > duration) {
                newProgress = duration;
            }
            exoPlayer.seekTo(newProgress);
        }

        @Override
        public void onTouchEventUp() {
            if (isVideoFirstFrame) {
                mViewControl.hideFloatView();
            }
        }
    }
}
